#pragma once

#include "Storage.h"
#include <cmath>
#include <string>

namespace MockItNow
{
	template<typename T>
	std::string CompareByValue(const Storage<T>& lhs, const Storage<T>& rhs)
	{
		if ((lhs.value == rhs.value) == false)
			return MakeFailureString("Compare by value failed. ", lhs.value, rhs.value); 

		return "";
	}

	template<>
	inline std::string CompareByValue(const Storage<char*>& lhs, const Storage<char*>& rhs)
	{
		if (strcmp(lhs.value, rhs.value) != 0 )
			return MakeFailureString("Compare by value failed. ", lhs.value, rhs.value); 

		return "";
	}

	template<>
	inline std::string CompareByValue(const Storage<float>& lhs, const Storage<float>& rhs)
	{
		const float epsilon = 1e-6f;

		if (std::fabsf(lhs.value - rhs.value) > epsilon)
			return MakeFailureString("Compare by value failed. ", lhs.value, rhs.value); 

		return "";
	}

	template<typename T>
	std::string CompareByMemory(const Storage<T>& lhs, const Storage<T>& rhs)
	{
		if (std::memcmp(&lhs.value, &rhs.value, sizeof(lhs.value)) != 0)
			return MakeFailureString("Compare by memory failed. ", lhs.value, rhs.value); 

		return "";
	}

	template<typename T>
	std::string CompareByAddress(const Storage<T>& lhs, const Storage<T>& rhs)
	{
		if (lhs.address != rhs.address)
			return MakeFailureString("Compare by address failed. ", lhs.address, rhs.address); 

		return "";
	}
}
